/**
 * Wrapper class for the bing maps service.
 * 
 * @author Kim Pommert
 * @version %I%, %G%
 */
qx.Class.define("qooxdoosample.microsoft.bing.maps.BMapsWrapper",
{
	extend: qx.core.Object,
	implement: qooxdoosample.cocktail.maps.IDynamicMap,
	
	/**
	 * Class constructor.
	 * Instantiates an object of that class.
	 * 
	 * @param mapContainerId	{String} ID of the div container the map will be deployed to
	 */
	construct: function(mapContainerId)
	{
		this.base(arguments);
		this.setBMap(new VEMap(mapContainerId));
		// bing maps must be loaded after initialization of the VEMap object
		this.getBMap().LoadMap();
		this.hideControls();
    },
    
    statics:
    {
    	/**
    	 * Every load map request needs a zoom level. If no specific level
    	 * is given, this value is used.
    	 */
    	DEFAULT_ZOOM_LEVEL: 13
    },
	
	properties:
	{
		/**
		 * The bing maps object.
		 */
		bMap:
		{
			nullable: true,
			init: null,
			check: "VEMap"
		}
	},
	
	members:
	{
		/**
		 * Get the bing map object
		 * 
		 * @return	{Object} The VEMap object
		 * @see qooxdoosample.cocktail.maps.IMap#getMap()
		 */
		getMap: function()
		{
			return this.getBMap();
		},
		
		/**
		 * Set the bing map object.
		 * 
		 * @param value	{Object} the VEMap object
		 * @see qooxdoosample.cocktail.maps.IMap#setMap()
		 */
		setMap: function(value)
		{
			this.setBMap(value);
		},
		
		/**
		 * Set the center of the map to the specified coordinates.
		 * 
		 * @param position	{qooxdoosample.cocktail.util.LatLng} Coordinates for new center of the map
		 * @see qooxdoosample.cocktail.maps.IMap#setCenter()
		 */
		setCenter: function(position)
		{
			this.getBMap().LoadMap(this.__convertLatLngToBingFormat(position), this.self(arguments).DEFAULT_ZOOM_LEVEL);
		},
		
		/**
		 * Get the current position the map is centered on.
		 * 
		 * @return	{qooxdoosample.cocktail.util.LatLng} Coordinates of the current center point
		 * @see qooxdoosample.cocktail.maps.IMap#getCenter()
		 */
		getCenter: function()
		{
			var bLatLng = this.getBMap().GetCenter();
			return new qooxdoosample.cocktail.util.LatLng(bLatLng.Latitude, bLatLng.Longitude); 
		},

		/**
		 * Set the zoom level of the map.
		 * 
		 * @param level	{Number} The zoom level
		 * @see qooxdoosample.cocktail.maps.IMap#setZoomLevel()
		 */
		setZoomLevel: function(level)
		{
			this.getBMap().SetZoomLevel(level);
		},
		
		/**
		 * Get the current zoom level of the map
		 * 
		 * @return	{Number} The zoom level
		 * @see qooxdoosample.cocktail.maps.IMap#getZoomLevel()
		 */
		getZoomLevel: function()
		{
			return this.getBMap().GetZoomLevel();
		},
		
		/**
		 * Get the current coordinates of the south west and north east corner of the map.
		 * 
		 * @return	{qooxdoosample.cocktail.util.Boundaries} The boundaries of the map 
		 * @see qooxdoosample.cocktail.maps.IMap#getMapBoundaries()
		 */
		getMapBoundaries: function()
		{
			var view = this.getBMap().GetMapView();
            var bNE = view.TopRightLatLong;
            var bSW = view.BottomLeftLatLong;
			
			var southWest = new qooxdoosample.cocktail.util.LatLng(bSW.Latitude, bSW.Longitude);
			var northEast = new qooxdoosample.cocktail.util.LatLng(bNE.Latitude, bNE.Longitude);
			
			return new qooxdoosample.cocktail.util.Boundaries(southWest, northEast); 
		},
		
		/**
		 * Display the default bing maps control panel.
		 * 
		 * @see qooxdoosample.cocktail.maps.IMap#showControls()
		 */
		showControls: function()
		{
			this.getBMap().ShowDashboard();
		},
		
		/**
		 * Hide the bing maps control panel.
		 * 
		 * @see qooxdoosample.cocktail.maps.IMap#hideControls()
		 */
		hideControls: function()
		{
			this.getBMap().HideDashboard();
		},
		
		/**
		 * Add an overlay to the map.
		 * Typical overlays are Markers, Routes or Shapes.
		 * 
		 * @param overlay	{qooxdoosample.cocktail.util.overlays.Overlay} The overlay that will be added to the map
		 * @see qooxdoosample.cocktail.maps.IMap#addOverlay()
		 */
		addOverlay: function(overlay)
		{
			if(overlay instanceof qooxdoosample.cocktail.util.overlays.Marker)
			{
				// get markers position
				var bPoint = this.__convertLatLngToBingFormat(overlay.getPosition());
				var shape = new VEShape(VEShapeType.Pushpin, bPoint);
				
				
				// set the markers icon
				if(overlay.getCustomIcon() != null){
					customIcon = overlay.getCustomIcon();
					overlayIcon = "<img src=\"" +customIcon.getImage() + 
									"\" width=\"" + customIcon.getWidth() + 
									"\" height=\"" + customIcon.getHeight() + "\">";
					shape.SetCustomIcon(overlayIcon);
				}
                				
				// set custom info text
				if(overlay.getInfoText() != null){
					shape.SetDescription(overlay.getInfoText());
				}
				
				// add marker to map
				this.getBMap().AddShape(shape);
				
			} 
			else if(overlay instanceof qooxdoosample.cocktail.util.overlays.Polygon)
			{
				// get all points of the polygon and convert them to bing format
				var bPoints = new Array();
				var points = overlay.getPoints();
				
				for(i=0; i<points.length; i++)
				{
					bPoints[i] = this.__convertLatLngToBingFormat(points[i]);
				}
				
				var shape = new VEShape(VEShapeType.Polygon, bPoints);
				
				// convert line color to rgb and set the property of the overlay
				var lineRGB = this.__hexToRGB(overlay.getColor());
				var lineColor = new VEColor(lineRGB[0], lineRGB[1], lineRGB[2], overlay.getLineOpacity());
				shape.SetLineColor(lineColor);
	
				shape.SetLineWidth(overlay.getWidth());
				
				//Set the fill color
				var fillRGB = this.__hexToRGB(overlay.getFillColor());
         		var fillColor = new VEColor(fillRGB[0], fillRGB[1], fillRGB[2], overlay.getFillOpacity());
         		shape.SetFillColor(fillColor);
				
				// add polygon to map							
				this.getBMap().AddShape(shape);
			}
			else if(overlay instanceof qooxdoosample.cocktail.util.overlays.Polyline)
			{
				// get all points of the polyline and convert them to bing format
				var bPoints = new Array();
				var points = overlay.getPoints();
				
				for(i=0; i<points.length; i++)
				{
					bPoints[i] = this.__convertLatLngToBingFormat(points[i]);
				}
				
				var shape = new VEShape(VEShapeType.Polyline, bPoints);
				
				// convert line color to rgb and set the property of the overlay
				var lineRGB = this.__hexToRGB(overlay.getColor());
				var lineColor = new VEColor(lineRGB[0], lineRGB[1], lineRGB[2], overlay.getLineOpacity());
				shape.SetLineColor(lineColor);
	
				shape.SetLineWidth(overlay.getWidth());

				// add polyline to map							
				this.getBMap().AddShape(shape);	
			}
		},
		
		/**
		 * Converts HTML hex color declaration to RGB values.
		 * 
		 * @param hex	{String} The HTML hex color value
		 * @return		{Array} An array with [R,G,B] value as integer
		 */
		__hexToRGB: function(hex)
		{
			//hex = this.cutHex(hex);
			var rgb = new Array();
			rgb[0] = this.__hexToR(hex);
			rgb[1] = this.__hexToG(hex);
			rgb[2] = this.__hexToB(hex);
			return rgb;
		},
		
		/**
		 * Cuts the # symbol from a HTML color value string.
		 * 
		 * @param h	{String} The HTML hex color value
		 * @return	{String} The input string without the # symbol
		 */
		__cutHex: function(h) { return (h.charAt(0)=="#") ? h.substring(1,7):h; },
		
		/**
		 * Gets the red value from an HTML hex color and converts
		 * it to an RGB value.
		 * 
		 * @param h	{String} The HTML hex color value
		 * @return	{Integer} The red value as RGB integer
		 */
		__hexToR: function(h) { return parseInt((this.__cutHex(h)).substring(0,2),16); },
		
		/**
		 * Gets the green value from an HTML hex color and converts
		 * it to an RGB value.
		 * 
		 * @param h	{String} The HTML hex color value
		 * @return	{Integer} The green value as RGB integer
		 */
		__hexToG:	function(h) { return parseInt((this.__cutHex(h)).substring(2,4),16); },
		
		/**
		 * Gets the blue value from an HTML hex color and converts
		 * it to an RGB value.
		 * 
		 * @param h	{String} The HTML hex color value
		 * @return	{Integer} The blue value as RGB integer
		 */
		__hexToB:	function(h) { return parseInt((this.__cutHex(h)).substring(4,6),16); },
		
		/**
		 * Remove all overlays from the map.
		 * 
		 * @see qooxdoosample.cocktail.maps.IMap#clearOverlays()
		 */
		clearOverlays: function()
		{
			this.getBMap().DeleteAllShapes();;	
		},
			
		/**
		 * Converts the generic geographic coordinates to bing specific format.
		 * 
		 * @param value	{qooxdoosample.cocktail.util.LatLng} The coordinates
		 * @return	{Object} The coordinates in bing format
		 */
		__convertLatLngToBingFormat: function(value)
		{
			return new VELatLong(value.getLatitude(), value.getLongitude());
		},
		
		
		/*
		 * MAP CONTROLS
		 */
		 
		/**
		 * Change the displayed type of the map
		 * 
		 * @param type	{Number} Constant value of the map type
		 * @see qooxdoosample.cocktail.maps.IDynamicMap#setMapType()
		 */ 
		setMapType: function(type)
		{
			if(type == qooxdoosample.cocktail.maps.IDynamicMap.MAP_TYPE_NORMAL)
				this.getBMap().SetMapStyle(VEMapStyle.Road);
			else if(type == qooxdoosample.cocktail.maps.IDynamicMap.MAP_TYPE_SATELLITE)
				this.getBMap().SetMapStyle(VEMapStyle.Aerial);
			else if(type == qooxdoosample.cocktail.maps.IDynamicMap.MAP_TYPE_HYBRID)
				this.getBMap().SetMapStyle(VEMapStyle.Hybrid);
		},
		
		/**
		 * Increases the zoom level of the map
		 * 
		 * @see qooxdoosample.cocktail.maps.IDynamicMap#zoomIn()
		 */
		zoomIn: function()
		{
			this.getBMap().ZoomIn();
		},
		
		/**
		 * Decreases the zoom level of the map
		 * 
		 * @see qooxdoosample.cocktail.maps.IDynamicMap#zoomOut()
		 */
		zoomOut: function()
		{
			this.getBMap().ZoomOut();
		},
		
		/**
		 * Shifts the current map view to the west
		 * 
		 * @see qooxdoosample.cocktail.maps.IDynamicMap#moveLeft()
		 */
		moveLeft: function()
		{
			this.getBMap().Pan(-100, 0);
		},
		
		/**
		 * Shifts the current map view to the east
		 * 
		 * @see qooxdoosample.cocktail.maps.IDynamicMap#moveRight()
		 */
		moveRight: function()
		{
			this.getBMap().Pan(100, 0);
		},
		
		/**
		 * Shifts the current map view to the north
		 * 
		 * @see qooxdoosample.cocktail.maps.IDynamicMap#moveUp()
		 */
		moveUp: function()
		{
			this.getBMap().Pan(0, -100);
		},
		
		/**
		 * Shifts the current map view to the south
		 * 
		 * @see qooxdoosample.cocktail.maps.IDynamicMap#moveDown()
		 */
		moveDown: function()
		{
			this.getBMap().Pan(0, 100);
		}
		
	}
});